package com.yuncommunity.cloudlab.storage

import com.yuncommunity.cloudlab.utils.MyUtils
import net.bytebuddy.utility.RandomString
import net.coobird.thumbnailator.Thumbnails
import org.springframework.core.io.Resource
import org.springframework.core.io.UrlResource
import org.springframework.stereotype.Service
import org.springframework.util.FileSystemUtils
import org.springframework.web.multipart.MultipartFile
import java.io.File
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
import java.util.stream.Stream


@Service
class FileStorageImpl : FileStorage {
    var rootLocation: Path = Paths.get("upload")

    override fun store(dir: String, file: MultipartFile): String {
        var f = this.rootLocation.resolve(dir).toFile()
        if (!f.exists()) {
            Files.createDirectories(this.rootLocation.resolve(dir))
        }
        if (file.originalFilename == null) {
            return ""
        }
        var newName = RandomString.make(32) + MyUtils.getExtByName(file.originalFilename!!);
        if (dir == "avatar") {
            Thumbnails.of(file.inputStream)
                    .size(200, 200)
                    .toFile(this.rootLocation.resolve("$dir/$newName").toFile())
        } else {
            Files.copy(file.inputStream, this.rootLocation.resolve("$dir/$newName"))
        }
        return newName
    }

    override fun loadFile(filename: String): Resource? {
        val file = rootLocation.resolve(filename)
        val resource = UrlResource(file.toUri())

        if (resource.exists() || resource.isReadable) {
            return resource
        } else {
            return null
        }
    }

    override fun newFile(filename: String): File {
        return rootLocation.resolve(filename).toFile()
    }

    override fun deleteAll() {
        FileSystemUtils.deleteRecursively(rootLocation.toFile())
    }

    override fun init() {
        val f = rootLocation.toFile()
        if (!f.exists()) {
            Files.createDirectory(rootLocation)
        }
    }

    override fun loadFiles(): Stream<Path> {
        return Files.walk(this.rootLocation, 1)
                .filter { path -> path != this.rootLocation }
                .map(this.rootLocation::relativize)
    }
}